#include <iostream>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <deque>

using namespace std;

const int maxN = 10000;
const int maxY = 30;

map<pair<int, int>, vector<int> > neis;
vector<pair<int, int> > edges;
set<pair<int, int> > hash;
vector<int> a[100];
int	n, m, time_mark;
int x[maxN], y[maxN];
int	mark[maxN], color[maxN];

bool compareX(int i, int j)
{
	return x[i] < x[j];
}

vector<int>& get_nei(int u, int v)
{
	int i = min(u, v), j = max(u, v);
	return neis[make_pair(i, j)];
}

void add_tri(int u, int v, int k)
{
	neis[make_pair(min(u, v), max(u, v))].push_back(k);
	neis[make_pair(min(u, k), max(u, k))].push_back(v);
	neis[make_pair(min(k, v), max(k, v))].push_back(u);
	edges.push_back(make_pair(min(u, v), max(u, v)));
	edges.push_back(make_pair(min(u, k), max(u, k)));
	edges.push_back(make_pair(min(v, k), max(v, k)));
}

bool dfs(int u, int v)
{
	vector<int> &nei = get_nei(u, v);
	hash.insert(make_pair(u, v));
	for (int i = 0; i < nei.size(); ++i)
	{
		int k = nei[i];
		if (mark[k] == time_mark && color[k] != 3 - color[u] - color[v]) return false;
		if (mark[k] < time_mark)
		{
			mark[k] = time_mark;
			color[k] = 3 - color[u] - color[v];
			if (!dfs(min(u, k), max(u, k))) return false;
			if (!dfs(min(v, k), max(v, k))) return false;
		}
	}
	return true;
}

int	main()
{
	int task;
	scanf("%d", &task);
	for (int now_case = 0; now_case < task; ++now_case)
	{
		cin >> n;
		for (int i = 0; i < maxY; ++i) a[i].clear();
		for (int i = 0; i < n; ++i)
		{
			cin >> x[i] >> y[i];
			a[y[i]].push_back(i);
		}

		for (int i = 0; i < maxY; ++i) 
		{
			sort(a[i].begin(), a[i].end(), compareX);
		}

		edges.clear();
		neis.clear();
		bool no_edge = true;

		for (int i = 0; i < maxY - 1; ++i) if (a[i].size() > 1) no_edge = false;
		for (int i = 0; i < maxY - 1; ++i)
		{
			int j = i + 1;
			int u = a[i].size() - 1, v = a[j].size() - 1;

			while (v >= 0 && u > 0 && x[a[j][v]] < x[a[i][u - 1]]) 
			{
//				cout << x[a[j][v]] << x[a[i][u - 1]] << x[a[i][u]] << endl;
				--u;
			}
			while (u >= 0 && v > 0 && x[a[i][u]] < x[a[j][v - 1]]) --v;

			while (u >= 0 && v >= 0)
			{
				no_edge = false;
				if (u > 0 && (v == 0 || x[a[i][u - 1]] > x[a[j][v - 1]]))
				{
//					puts("here");
					add_tri(a[i][u - 1], a[j][v], a[i][u]);
					--u;
				} else
				if (v > 0 && (u == 0 || x[a[j][v - 1]] > x[a[i][u - 1]]))
				{
					add_tri(a[j][v - 1], a[j][v], a[i][u]);
					--v;
				} else
					break;
			}
		}

		if (no_edge)
		{
			printf("Case #%d: 1\n", now_case + 1);
			continue;
		}

		if (edges.size() == 0)
		{
			printf("Case #%d: 2\n", now_case + 1);
			continue;
		}

		hash.clear();
		bool checked = false;
		time_mark = 0;
		memset(mark, 0, sizeof(mark));
		for (int i = 0; i < edges.size(); ++i)
		{
			int u = edges[i].first;
			int v = edges[i].second;
			if (hash.count(make_pair(u, v)) || hash.count(make_pair(v, u))) continue;
			++time_mark;
			mark[u] = mark[v] = time_mark;
			color[u] = 0;
			color[v] = 1;
			if (!dfs(min(u, v), max(u, v)))
			{
				checked = true;
				break;
			}
		}

		printf("Case #%d: %d\n", now_case + 1, checked ? 4 : 3);
	}
	return 0;
}
